package com.my.mygateway.handler;

import com.my.mycommoncore.utils.JsonUtils;
import com.my.mycommoncore.utils.ServletUtil;
import com.my.mycommondomain.domian.R;
import com.my.mycommondomain.domian.ResultCode;
import com.my.mycommondomain.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.reactive.resource.NoResourceFoundException;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
//@Order(-1)
@Slf4j
@Configuration
public class GatewayExceptionHandler implements ErrorWebExceptionHandler {
    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        ServerHttpResponse response = exchange.getResponse();
        if(response.isCommitted()){
            return Mono.error(ex);
        }
        String retMsg=ResultCode.ERROR.getMsg();
        int retCode=ResultCode.ERROR.getCode();
        if(ex instanceof NoResourceFoundException){
            retMsg = ResultCode.SERVICE_NOT_FOUND.getMsg();
            retCode = ResultCode.SERVICE_NOT_FOUND.getCode();
        } else if (ex instanceof ServiceException) {
            //自定义异常
            retMsg = ex.getMessage();
            retCode = ((ServiceException) ex).getCode();
        }
        int httpCode = Integer.parseInt(String.valueOf(retCode).substring(0,3));
        log.error("[网关异常处理]请求路径:{},异常信息:{}", exchange.getRequest().getPath(), ex.getMessage());
        return webFluxResponseWriter(response, HttpStatus.valueOf(httpCode),retMsg, retCode);
    }
    private static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value, int code) {
        return webFluxResponseWriter(response, MediaType.APPLICATION_JSON_VALUE,status, value, code);
    }
    private static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, String contentType,HttpStatus status, Object value, int code) {
        response.setStatusCode(status);
        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType); //设置响应体内容类型为json
        R<?> result = R.fail(code, value.toString()); //按照约定响应数据结构，构建响应体内容
        DataBuffer dataBuffer = response.bufferFactory().wrap(JsonUtils.objToString(result).getBytes());
        return response.writeWith(Mono.just(dataBuffer)); //将响应体内容写入响应体
    }
}
